#pragma once

#include <iostream>
#include <json/json.h>
#include <mysql/mysql.h>

#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include <websocketpp/frame.hpp>
using websocketpp::lib::bind;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::placeholders::_3;
typedef websocketpp::server<websocketpp::config::asio> server;
typedef websocketpp::connection_hdl connection_hdl;
typedef server::message_ptr message_ptr;

#include "send_to_qml.hpp"
#include "UserManagement.hpp"
#include "MsgMgt.hpp"
#include "utility.hpp"
#include "GroupMgt.hpp"


class MsgRouting
{
public:
    MsgRouting(){};
    ~MsgRouting(){};
    void add_friend(std::string my, std::string your, std::string verification,server *s,connection_hdl h);
    void get_msg(int user_id, std::string name); // 把数据库中未递达的消息发送给用户
    void send_text_msg(std::string send_name,std::string recv_name,std::string content);
    void send_emoji_msg(std::string send_name,std::string recv_name,std::string content);
    void send_file_msg(std::string send_name,std::string recv_name,std::string file_name,std::string file_size);
    void send_group_msg(std::string group_name, std::string user_name,std::string kind,std::string c1,std::string c2);
    
private:
    MsgMgt msg_mgt_;
    GroupMgt group_mgt_;
};

void MsgRouting::add_friend(std::string my, std::string your, std::string verification,server *s,connection_hdl h)
{
    // 如果目标用户不存在
    if(!UserMgt::user_exists(your))
    {
        Json::Value root;
        root["op"] = "user_not_exists";
        std::string jsonString = root.toStyledString();
        std::cout << "MsgRouting::add_friend 目标用户不存在发送，前" << std::endl;
        send_to_qml::send_text(UserMgt::hdl_of_user(my), jsonString);
        std::cout << "MsgRouting::add_friend 目标用户不存在发送，后" << std::endl;
        
        // std::cout << "MsgRouting::add_friend 目标用户不存在发送，前" << std::endl;
        // s->send(UserMgt::hdl_of_user(my), jsonString, websocketpp::frame::opcode::TEXT);
        // std::cout << "MsgRouting::add_friend 目标用户不存在发送，后" << std::endl;
        return;
    }

    // 构建消息
    Json::Value root;
    root["op"] = "notify";
    root["kind"] = "add_friend";
    root["who_nickname"] = my;
    root["verification"] = verification;
    root["time"] = get_time();
    std::string jsonString = root.toStyledString();

    if(UserMgt::is_user_online(your))
    {
        //std::cout << "目标用户在线" << std::endl;
        std::cout << "MsgRouting::add_friend 一进来就发送，后" << std::endl;
        send_to_qml::send_text(UserMgt::hdl_of_user(your), jsonString);
    }
    else // 目标用户不在线
    {
        //std::cout << "目标用户不在线" << std::endl;
        int send = UserMgt::id_of_nickname(my);
        int recv = UserMgt::id_of_nickname(your);
        // delivered undelivered 送达、未送达
        msg_mgt_.insert_msg(send,recv,"notify",jsonString,"undelivered");
    }


    Json::Value json_value;
    json_value["op"] = "popup_msg";
    json_value["kind"] = "yes";
    json_value["reason"] = "申请发送成功!";
    std::string str = json_value.toStyledString();
    send_to_qml::send_text(UserMgt::hdl_of_user(my), str);
}

void MsgRouting::send_text_msg(std::string send_name,std::string recv_name,std::string content)
{
    // 如果目标用户不存在
    if(!UserMgt::user_exists(recv_name))
    {
        std::cout << "MsgRouting::send_text_msg 目标用户不存在" << std::endl;
        return;
    }

    // 构建消息
    Json::Value root;
    root["op"] = "msg";
    root["kind"] = "text";
    root["send_name"] = send_name;
    root["recv_name"] = recv_name;
    root["content"] = content;
    root["time"] = get_time();
    std::string jsonString = root.toStyledString();

    if(UserMgt::is_user_online(recv_name))
    {
        //std::cout << "目标用户在线" << std::endl;
        //std::cout << "MsgRouting::add_friend 一进来就发送，后" << std::endl;
        send_to_qml::send_text(UserMgt::hdl_of_user(recv_name), jsonString);
    }
    else // 目标用户不在线
    {
        // std::cout << "MsgRouting::send_text_msg 目标用户不在线" << std::endl;
        int send = UserMgt::id_of_nickname(send_name);
        int recv = UserMgt::id_of_nickname(recv_name);
        // delivered undelivered 送达、未送达
        msg_mgt_.insert_msg(send,recv,"msg_text",jsonString,"undelivered");
    }
}

void MsgRouting::send_emoji_msg(std::string send_name,std::string recv_name,std::string content)
{
    // 如果目标用户不存在
    if(!UserMgt::user_exists(recv_name))
    {
        std::cout << "MsgRouting::send_text_msg 目标用户不存在" << std::endl;
        return;
    }

    // 构建消息
    Json::Value root;
    root["op"] = "msg";
    root["kind"] = "emoji";
    root["send_name"] = send_name;
    root["recv_name"] = recv_name;
    root["content"] = content;
    root["time"] = get_time();
    std::string jsonString = root.toStyledString();

    if(UserMgt::is_user_online(recv_name))
    {
        //std::cout << "目标用户在线" << std::endl;
        //std::cout << "MsgRouting::add_friend 一进来就发送，后" << std::endl;
        send_to_qml::send_text(UserMgt::hdl_of_user(recv_name), jsonString);
    }
    else // 目标用户不在线
    {
        // std::cout << "MsgRouting::send_text_msg 目标用户不在线" << std::endl;
        int send = UserMgt::id_of_nickname(send_name);
        int recv = UserMgt::id_of_nickname(recv_name);
        // delivered undelivered 送达、未送达
        msg_mgt_.insert_msg(send,recv,"msg_emoji",jsonString,"undelivered");
    }
}

void MsgRouting::send_file_msg(std::string send_name,std::string recv_name,std::string file_name,std::string file_size)
{
    // 如果目标用户不存在
    if(!UserMgt::user_exists(recv_name))
    {
        std::cout << "MsgRouting::send_text_msg 目标用户不存在" << std::endl;
        return;
    }

    // 构建消息
    Json::Value root;
    root["op"] = "msg";
    root["kind"] = "file";
    root["send_name"] = send_name;
    root["recv_name"] = recv_name;
    root["file_name"] = file_name;
    root["file_size"] = file_size;
    root["time"] = get_time();
    std::string jsonString = root.toStyledString();

    if(UserMgt::is_user_online(recv_name))
    {
        //std::cout << "目标用户在线" << std::endl;
        //std::cout << "MsgRouting::add_friend 一进来就发送，后" << std::endl;
        send_to_qml::send_text(UserMgt::hdl_of_user(recv_name), jsonString);
    }
    else // 目标用户不在线
    {
        std::cout << "MsgRouting::send_file_msg 目标用户不在线" << std::endl;
        int send = UserMgt::id_of_nickname(send_name);
        int recv = UserMgt::id_of_nickname(recv_name);
        // delivered undelivered 送达、未送达
        msg_mgt_.insert_msg(send,recv,"msg_file",jsonString,"undelivered");
    }
}



// 把数据库中未递达的消息发送给用户
void MsgRouting::get_msg(int user_id, std::string name) // user_id 是发起 get_msg 的用户，name 是这个用户给的参数，其它用户 or 群组的name
{
    if(group_mgt_.group_exist(name))
    {
        std::vector<std::vector<std::string>> msg_group_vv;
        int group_id = group_mgt_.group_id_of_name(name);
        msg_group_vv = msg_mgt_.get_msg(-1,group_id,"group_msg","undelivered");
        for(auto v : msg_group_vv)
        {
            send_to_qml::send_text(UserMgt::hdl_of_user(UserMgt::nickname_of_id(user_id)), v[4]);
        }
        return;
    }

    std::vector<std::vector<std::string>> msg_vv;
    std::vector<std::string> row_v;

    std::cout << "MsgRouting::get_msg" << name << std::endl;

    if(name == "notify")
    {
        msg_vv = msg_mgt_.get_msg(-1,user_id,"notify","undelivered");
    }
    else
    {
        // name 发给 user_id 的所有未递达消息
        msg_vv = msg_mgt_.get_msg(UserMgt::id_of_nickname(name),user_id,"msg_text","undelivered");
        std::vector<std::vector<std::string>> msg_vv2;
        msg_vv2 = msg_mgt_.get_msg(UserMgt::id_of_nickname(name),user_id,"msg_emoji","undelivered");
        std::vector<std::vector<std::string>> msg_vv3;
        msg_vv3 = msg_mgt_.get_msg(UserMgt::id_of_nickname(name),user_id,"msg_file","undelivered");

        // user_id 发给 name 的所有未递达消息
        std::vector<std::vector<std::string>> msg_vv4;
        msg_vv4 = msg_mgt_.get_msg(user_id,UserMgt::id_of_nickname(name),"msg_text","undelivered");
        std::vector<std::vector<std::string>> msg_vv5;
        msg_vv5 = msg_mgt_.get_msg(user_id,UserMgt::id_of_nickname(name),"msg_emoji","undelivered");
        std::vector<std::vector<std::string>> msg_vv6;
        msg_vv6 = msg_mgt_.get_msg(user_id,UserMgt::id_of_nickname(name),"msg_file","undelivered");


        // 合并多个查询结果
        msg_vv.insert(msg_vv.end(), msg_vv2.begin(), msg_vv2.end()); 
        msg_vv.insert(msg_vv.end(), msg_vv3.begin(), msg_vv3.end()); 
        msg_vv.insert(msg_vv.end(), msg_vv4.begin(), msg_vv4.end());
        msg_vv.insert(msg_vv.end(), msg_vv5.begin(), msg_vv5.end());
        msg_vv.insert(msg_vv.end(), msg_vv6.begin(), msg_vv6.end());     
    }

    // 重新发送之前未递达的消息
    for(auto v : msg_vv)
    {
        if(v[3] == "notify") // v[3] 即 kind 字段
        {
            // v[4] 是 content 字段，一般就是需要发送的内容
            std::cout << UserMgt::hdl_of_user(UserMgt::nickname_of_id(user_id)).lock().get() << std::endl;
            send_to_qml::send_text(UserMgt::hdl_of_user(UserMgt::nickname_of_id(user_id)), v[4]);
        }
        if(v[3] == "msg_text")
        {
            // std::cout << "MsgRouting::get_msg" << name << v[4] << std::endl;
            send_to_qml::send_text(UserMgt::hdl_of_user(UserMgt::nickname_of_id(user_id)), v[4]);
        }
        if(v[3] == "msg_emoji")
        {
            send_to_qml::send_text(UserMgt::hdl_of_user(UserMgt::nickname_of_id(user_id)), v[4]);
        }
        if(v[3] == "msg_file")
        {
            send_to_qml::send_text(UserMgt::hdl_of_user(UserMgt::nickname_of_id(user_id)), v[4]);
        }
    }
    
}



void MsgRouting::send_group_msg(std::string group_name, std::string user_name,std::string kind,std::string c1,std::string c2)
{
    

    // 构建消息
    Json::Value root;
    root["op"] = "group_msg";
    root["group_name"] = group_name;
    root["user_name"] = user_name;
    root["kind"] = kind;
    root["c1"] = c1;
    root["c2"] = c2;
    root["time"] = get_time();
    std::string jsonString = root.toStyledString();

    // 先把这条群消息暂存起来
    int send = UserMgt::id_of_nickname(user_name);
    int recv = group_mgt_.group_id_of_name(group_name);
    msg_mgt_.insert_msg(send,recv,"group_msg",jsonString,"undelivered");

    // 获取所有群成员的 id, 并从中去除掉自己的
    int my_id = UserMgt::id_of_nickname(user_name);
    std::vector<int> user_ids = group_mgt_.ids_of_group(group_mgt_.group_id_of_name(group_name));
    user_ids.erase(std::remove_if(user_ids.begin(), user_ids.end(), 
    [my_id](int x) { return x == my_id; }), user_ids.end()); //从数组中移除自己的id

    // 遍历每一个群成员的 id ，如果 ta 在线，就给 ta 发这条消息
    for (const auto& user_id : user_ids) 
    {
        std::string name = UserMgt::nickname_of_id(user_id);
        std::cout << "MsgRouting::send_group_msg for循环内" << name << std::endl;
        if(UserMgt::is_user_online(name))
        {
            send_to_qml::send_text(UserMgt::hdl_of_user(name), jsonString);
        }
    }
    
}
